package co.gov.medellin.ssti.sub.paoyer.administration.dao;

import java.sql.Connection;
import java.sql.Statement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Collection;

import java.sql.PreparedStatement;

import co.gov.medellin.ssti.sub.paoyer.administration.model.vo.FlexValueVO;

/**
 * DAO para crear, consultar, actualizar y eliminar registros en la tabla
 * TCS_VALOR_FLEXIBLE.
 * 
 * @author Rene.Rangel@consult-soft.com
 * @version 1.0
 */

public class FlexValueDAO {
	/**
	 * Conexion a la base de datos.
	 */
	private Connection conn = null;

	/**
	 * Constructor que recibe como parametro la conexion con la base de datos.
	 * 
	 * @param conn
	 *            Conexion con la base de datos.
	 */

	public FlexValueDAO(Connection conn) {
		this.conn = conn;
	}

	public Collection<FlexValueVO> findFlexValueByCriterea(FlexValueVO criterea)
			throws SQLException {

		String query = "SELECT vafl.codigo, vafl.codigo_valor, "
				+ "vafl.nombre, vafl.descripcion, "
				+ "vafl.usuario_crea, vafl.terminal_crea, "
				+ "vafl.usuario_modifica, vafl.terminal_modifica, "
				+ "to_char(vafl.desde_vigencia,'yyyy-mm-dd') desde_vigencia, "
				+ "to_char(vafl.hasta_vigencia,'yyyy-mm-dd') hasta_vigencia, "
				+ "vafl.vigencia, vafl.tvf_codigo "
				+ "FROM tcs_valor_flexible vafl ";

		String filters = "";
		// Filtro por Codigo Valor
		if ((criterea.getFlexValueCustomCode() != null)
				&& !(criterea.getFlexValueCustomCode().equals(""))) {
			filters = filters + " AND UPPER(vafl.codigo_valor) = '"
					+ criterea.getFlexValueCustomCode().toUpperCase() + "' ";
		}
		// Filtro por Nombre
		if ((criterea.getFlexValueName() != null)
				&& !(criterea.getFlexValueName().equals(""))) {
			filters = filters + " AND UPPER(vafl.nombre) LIKE '%"
					+ criterea.getFlexValueName().toUpperCase() + "%' ";
		}
		// Filtro por Descripcion
		if ((criterea.getFlexValueDescription() != null)
				&& !(criterea.getFlexValueDescription().equals(""))) {
			filters = filters + " AND UPPER(vafl.descripcion) LIKE '%"
					+ criterea.getFlexValueDescription().toUpperCase() + "%' ";
		}
		// Filtro por Vigencia
		if ((criterea.getFlexValueUse() != null)
				&& !(criterea.getFlexValueUse().equals(""))) {
			filters = filters + " AND UPPER(vafl.vigencia) = '"
					+ criterea.getFlexValueUse().toUpperCase() + "' ";
		}
		// Filtro por Desde Vigencia
		if ((criterea.getFlexValueEffectiveFrom() != null)
				&& !(criterea.getFlexValueEffectiveFrom().equals(""))) {
			filters = filters + " AND vafl.desde_vigencia = TO_DATE('"
					+ criterea.getFlexValueEffectiveFrom() + "','yyyy-mm-dd')";
		}
		// Filtro por Hasta Vigencia
		if ((criterea.getFlexValueEffectiveUntil() != null)
				&& !(criterea.getFlexValueEffectiveUntil().equals(""))) {
			filters = filters + " AND vafl.hasta_vigencia = TO_DATE('"
					+ criterea.getFlexValueEffectiveUntil() + "','yyyy-mm-dd')";
		}
		// Filtro por Codigo Interno del Tipo de Valor Flexible
		if ((criterea.getFlexValueTypeInternalCode() != null)
				&& !(criterea.getFlexValueTypeInternalCode().longValue() == 0)) {
			filters = filters + " AND vafl.tvf_codigo = "
					+ criterea.getFlexValueTypeInternalCode();
		}

		// Filtro por Codigo Interno del Valor Flexible
		if ((criterea.getFlexValueInternalCode() != null)
				&& !(criterea.getFlexValueInternalCode().longValue() == 0)) {
			filters = filters + " AND vafl.codigo = "
					+ criterea.getFlexValueInternalCode();
		}

		// Si hay filtros, entonces armar la clausula WHERE
		if (!filters.equals("")) {
			query = query + " WHERE " + filters.replaceFirst("AND", "");
		}
		Statement stm = null;
		ResultSet rst = null;
		ArrayList<FlexValueVO> flexValues = new ArrayList<FlexValueVO>();
		stm = conn.createStatement();
		rst = stm.executeQuery(query);

		while (rst.next()) {
			FlexValueVO flexValue = new FlexValueVO();

			flexValue.setFlexValueInternalCode(new Long(rst.getLong("codigo")));
			flexValue.setFlexValueName(rst.getString("nombre"));
			flexValue.setFlexValueDescription(rst.getString("descripcion"));
			flexValue.setFlexValueCustomCode(rst.getString("codigo_valor"));
			flexValue.setFlexValueWebUserCrea(rst.getString("usuario_crea"));
			flexValue.setFlexValueWebClientCrea(rst.getString("terminal_crea"));
			flexValue.setFlexValueWebUserModif(rst
					.getString("usuario_modifica"));
			flexValue.setFlexValueWebClientModif(rst
					.getString("terminal_modifica"));
			flexValue
					.setFlexValueEffectiveFrom(rst.getString("desde_vigencia"));
			flexValue.setFlexValueEffectiveUntil(rst
					.getString("hasta_vigencia"));
			flexValue.setFlexValueUse(rst.getString("vigencia"));
			flexValue.setFlexValueTypeInternalCode(new Long(rst
					.getLong("tvf_codigo")));
			flexValues.add(flexValue);
		}

		stm.close();
		return flexValues;
	}

	public FlexValueVO createFlexValue(FlexValueVO flexValue)
			throws SQLException {

		String strSQL = "";
		boolean result = false;
		PreparedStatement ps = null;
		strSQL = "INSERT INTO tcs_valor_flexible  (codigo, codigo_valor, nombre, "
				+ "descripcion, usuario_crea, terminal_crea, usuario_modifica, "
				+ "terminal_modifica, desde_vigencia, hasta_vigencia, vigencia, "
				+ "tvf_codigo) VALUES(scs_valor_flexible.nextval,?,?,?,?,?,?,?,TO_DATE(?,'yyyy-mm-dd'),TO_DATE(?,'yyyy-mm-dd'),?,?)";

		ps = conn.prepareStatement(strSQL);

		ps.setString(1, flexValue.getFlexValueCustomCode().toUpperCase());
		ps.setString(2, flexValue.getFlexValueName().toUpperCase());
		ps.setString(3, flexValue.getFlexValueDescription().toUpperCase());
		ps.setString(4, flexValue.getFlexValueWebUserCrea().toUpperCase());
		ps.setString(5, "WEB="
				+ flexValue.getFlexValueWebClientCrea().toUpperCase());
		ps.setString(6, flexValue.getFlexValueWebUserModif().toUpperCase());
		ps.setString(7, "WEB="
				+ flexValue.getFlexValueWebClientModif().toUpperCase());
		ps.setString(8, flexValue.getFlexValueEffectiveFrom());
		ps.setString(9, flexValue.getFlexValueEffectiveUntil());
		ps.setString(10, flexValue.getFlexValueUse().toUpperCase());
		ps.setLong(11, flexValue.getFlexValueTypeInternalCode().longValue());
		result = ps.execute();

		if (!result) {
			Statement stm = conn.createStatement();
			ResultSet rst = stm
					.executeQuery("SELECT scs_valor_flexible.currval FROM dual");
			if (rst.next()) {
				flexValue.setFlexValueInternalCode(new Long(rst.getLong(1)));
			}
			stm.close();
			rst.close();
		}

		ps.close();

		return flexValue;
	}

	public boolean updateFlexValue(FlexValueVO flexValue) throws SQLException {

		String strSQL = "UPDATE tcs_valor_flexible " + "SET codigo_valor = ?, "
				+ "nombre = ?, " + "descripcion = ?, "
				+ "usuario_modifica = ?, " + "terminal_modifica = ?, " +
				// "desde_vigencia = TO_DATE(?,'yyyy-mm-dd'), " +
				// "hasta_vigencia = TO_DATE(?,'yyyy-mm-dd'), " +
				// "vigencia = ?, " +
				"tvf_codigo = ? " + "WHERE codigo = ?";

		PreparedStatement ps = conn.prepareStatement(strSQL);
		ps.setString(1, flexValue.getFlexValueCustomCode().toUpperCase());
		ps.setString(2, flexValue.getFlexValueName().toUpperCase());
		ps.setString(3, flexValue.getFlexValueDescription().toUpperCase());
		ps.setString(4, flexValue.getFlexValueWebUserModif().toUpperCase());
		ps.setString(5, "WEB="
				+ flexValue.getFlexValueWebClientModif().toUpperCase());
		// ps.setString(6, flexValue.getFlexValueEffectiveFrom());
		// ps.setString(7, flexValue.getFlexValueEffectiveUntil());
		// ps.setString(8, flexValue.getFlexValueUse().toUpperCase());
		ps.setLong(6, flexValue.getFlexValueTypeInternalCode().longValue());
		ps.setLong(7, flexValue.getFlexValueInternalCode().longValue());

		boolean update = ps.execute();
		ps.close();
		return !update;

	}

	public boolean deleteFlexValue(FlexValueVO flexValue) throws SQLException {

		String strSQL = "DELETE tcs_valor_flexible WHERE codigo = ?";

		PreparedStatement ps = conn.prepareStatement(strSQL);

		ps.setLong(1, flexValue.getFlexValueInternalCode().longValue());

		boolean delete = ps.execute();
		ps.close();
		return !delete;

	}

	public Collection<FlexValueVO> findFlexValueTypeByCriterea(
			FlexValueVO criterea) throws SQLException {

		String query = "SELECT tivf.codigo, tivf.nombre, "
				+ "tivf.descripcion, to_char(tivf.desde_vigencia,'yyyy-mm-dd') desde_vigencia, "
				+ "to_char(tivf.hasta_vigencia,'yyyy-mm-dd') hasta_vigencia, tivf.vigencia, "
				+ "tivf.codigo_valor_aut, tivf.apl_codigo, "
				+ "apli.nombre aplicacion " + "FROM tcs_aplicacion apli, "
				+ "tcs_tipo_valor_flex tivf "
				+ "WHERE apli.codigo = tivf.apl_codigo ";

		String filters = "";
		// Filtro por Codigo interno del Tipo de valor Flexible
		if ((criterea.getFlexValueTypeInternalCode() != null)
				&& !(criterea.getFlexValueTypeInternalCode().longValue() == 0)) {
			filters = filters + " AND tivf.codigo = "
					+ criterea.getFlexValueTypeInternalCode().longValue();
		}
		// Filtro por Nombre del tipo de valor flexible
		if ((criterea.getFlexValueTypeName() != null)
				&& !(criterea.getFlexValueTypeName().equals(""))) {
			filters = filters + " AND UPPER(tivf.nombre) LIKE '%"
					+ criterea.getFlexValueTypeName().toUpperCase() + "%' ";
		}
		// Filtro por Descripcion del tipo de valor flexible
		if ((criterea.getFlexValueTypeDescription() != null)
				&& !(criterea.getFlexValueTypeDescription().equals(""))) {
			filters = filters + " AND UPPER(tivf.descripcion) LIKE '%"
					+ criterea.getFlexValueTypeDescription().toUpperCase()
					+ "%' ";
		}
		// Filtro por Vigencia
		if ((criterea.getFlexValueTypeUse() != null)
				&& !(criterea.getFlexValueTypeUse().equals(""))) {
			filters = filters + " AND UPPER(tivf.vigencia) = '"
					+ criterea.getFlexValueTypeUse().toUpperCase() + "' ";
		}
		// Filtro por Desde Vigencia
		if ((criterea.getFlexValueTypeEffectiveFrom() != null)
				&& !(criterea.getFlexValueTypeEffectiveFrom().equals(""))) {
			filters = filters + " AND tivf.desde_vigencia = TO_DATE('"
					+ criterea.getFlexValueTypeEffectiveFrom()
					+ "','yyyy-mm-dd')";
		}
		// Filtro por Hasta Vigencia
		if ((criterea.getFlexValueTypeEffectiveUntil() != null)
				&& !(criterea.getFlexValueTypeEffectiveUntil().equals(""))) {
			filters = filters + " AND tivf.hasta_vigencia = TO_DATE('"
					+ criterea.getFlexValueTypeEffectiveUntil()
					+ "','yyyy-mm-dd')";
		}
		// Filtro por Codigo Interno de la Aplicacion
		if ((criterea.getApplicationContextInternalCode() != null)
				&& !(criterea.getApplicationContextInternalCode().longValue() == 0)) {
			filters = filters + " AND apli.codigo = "
					+ criterea.getApplicationContextInternalCode();
		}
		// Filtro por Maneja Codigo
		if ((criterea.getFlexValueTypeAutomaticCustomCode() != null)
				&& !(criterea.getFlexValueTypeAutomaticCustomCode().equals(""))) {
			filters = filters
					+ " AND tivf.codigo_valor_aut = '"
					+ criterea.getFlexValueTypeAutomaticCustomCode()
							.toUpperCase() + "'";
		}

		// Si hay filtros, entonces armar la clausula WHERE
		if (!filters.equals("")) {
			query = query + filters;
		}

		Statement stm = null;
		ResultSet rst = null;
		ArrayList<FlexValueVO> flexValues = new ArrayList<FlexValueVO>();
		stm = conn.createStatement();
		rst = stm.executeQuery(query);

		while (rst.next()) {
			FlexValueVO flexValue = new FlexValueVO();

			/*
			 * 
			 * 
			 * tivf.desde_vigencia, "+ "tivf.hasta_vigencia, tivf.vigencia, "+
			 * "tivf.codigo_valor_aut, tivf.apl_codigo, "+ "tivf.nombre
			 * aplicacion
			 */

			flexValue.setFlexValueTypeInternalCode(new Long(rst
					.getLong("codigo")));
			flexValue.setFlexValueTypeName(rst.getString("nombre"));
			flexValue.setFlexValueTypeDescription(rst.getString("descripcion"));
			flexValue.setFlexValueTypeEffectiveFrom(rst
					.getString("desde_vigencia"));
			flexValue.setFlexValueTypeEffectiveUntil(rst
					.getString("hasta_vigencia"));
			flexValue.setFlexValueTypeUse(rst.getString("vigencia"));
			flexValue.setApplicationContextInternalCode(new Long(rst
					.getLong("apl_codigo")));
			flexValue.setApplicationContextName(rst.getString("aplicacion"));
			flexValue.setFlexValueTypeAutomaticCustomCode(rst
					.getString("codigo_valor_aut"));
			flexValues.add(flexValue);
			flexValue = null;
		}

		stm.close();
		return flexValues;
	}

	public FlexValueVO createFlexValueType(FlexValueVO flexValueType)
			throws SQLException {

		String strSQL = "";
		boolean result = false;
		PreparedStatement ps = null;
		strSQL = "INSERT INTO paoyer.tcs_tipo_valor_flex "
				+ "(codigo,nombre,descripcion,usuario_crea, "
				+ "terminal_crea,usuario_modifica,terminal_modifica, "
				+ "codigo_valor_aut," + "apl_codigo) VALUES "
				+ "(scs_tipo_valor_flex.nextval,?,?,?,?,?,?,?,?)";
		ps = conn.prepareStatement(strSQL);
		ps.setString(1, flexValueType.getFlexValueTypeName().toUpperCase());
		ps.setString(2, flexValueType.getFlexValueTypeDescription()
				.toUpperCase());
		ps.setString(3, flexValueType.getFlexValueTypeWebUserCrea()
				.toUpperCase());
		ps.setString(4, "WEB="
				+ flexValueType.getFlexValueTypeWebClientCrea().toUpperCase());
		ps.setString(5, flexValueType.getFlexValueTypeWebUserModif()
				.toUpperCase());
		ps.setString(6, "WEB="
				+ flexValueType.getFlexValueTypeWebClientModif().toUpperCase());
		// ps.setString(7, flexValueType.getFlexValueTypeEffectiveFrom());
		// ps.setString(8, flexValueType.getFlexValueTypeEffectiveUntil());
		// ps.setString(9, flexValueType.getFlexValueTypeUse());
		ps.setString(7, flexValueType.getFlexValueTypeAutomaticCustomCode()
				.toUpperCase());
		ps.setLong(8, flexValueType.getApplicationContextInternalCode()
				.longValue());
		result = ps.execute();

		if (!result) {
			Statement stm = conn.createStatement();
			ResultSet rst = stm
					.executeQuery("SELECT scs_tipo_valor_flex.currval FROM dual");
			if (rst.next()) {
				flexValueType.setFlexValueTypeInternalCode(new Long(rst
						.getLong(1)));
			}
			stm.close();
			rst.close();
		}

		ps.close();

		return flexValueType;
	}

	public boolean updateFlexValueType(FlexValueVO flexValueType)
			throws SQLException {

		String strSQL = "UPDATE tcs_tipo_valor_flex "
				+ "   SET nombre = ?, "
				+ "       descripcion = ?, "
				+ "       usuario_modifica = ?, "
				+ "       terminal_modifica = ?, "
				+
				// "       desde_vigencia = TO_DATE(?,'yyyy-mm-dd'), "+
				// "       hasta_vigencia = TO_DATE(?,'yyyy-mm-dd'), "+
				// "       vigencia = ?, "+
				"       codigo_valor_aut = ?, " + "       apl_codigo = ? "
				+ " WHERE codigo = ?";
		PreparedStatement ps = conn.prepareStatement(strSQL);
		ps.setString(1, flexValueType.getFlexValueTypeName().trim()
				.toUpperCase());
		ps.setString(2, flexValueType.getFlexValueTypeDescription().trim()
				.toUpperCase());
		ps.setString(3, flexValueType.getFlexValueTypeWebUserModif().trim()
				.toUpperCase());
		ps.setString(4, "WEB="
				+ flexValueType.getFlexValueTypeWebClientModif().trim()
						.toUpperCase());
		// ps.setString(5,
		// flexValueType.getFlexValueTypeEffectiveFrom().trim());
		// ps.setString(6,
		// flexValueType.getFlexValueTypeEffectiveUntil().trim());
		// ps.setString(7,
		// flexValueType.getFlexValueTypeUse().trim().toUpperCase());
		ps.setString(5, flexValueType.getFlexValueTypeAutomaticCustomCode()
				.trim().toUpperCase());
		ps.setLong(6, flexValueType.getApplicationContextInternalCode()
				.longValue());
		ps.setLong(7, flexValueType.getFlexValueTypeInternalCode().longValue());

		boolean updates = ps.execute();

		if (updates) {
			return false;
		}
		ps.close();

		return true;
	}

	public boolean deleteFlexValueType(FlexValueVO flexValueType)
			throws SQLException {

		String strSQL = "DELETE tcs_valor_flexible WHERE TVF_CODIGO = ?";
		PreparedStatement ps = conn.prepareStatement(strSQL);
		ps.setLong(1, flexValueType.getFlexValueTypeInternalCode().longValue());
		boolean delete = ps.execute();
		delete = ps.execute();
		ps.close();
		strSQL = "DELETE tcs_tipo_valor_flex WHERE codigo = ?";
		ps = conn.prepareStatement(strSQL);
		ps.setLong(1, flexValueType.getFlexValueTypeInternalCode().longValue());
		delete = ps.execute();
		ps.close();
		return (!delete);

	}

}